﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;

namespace TestGeocode
{
    public class TestHarness
    {
        //Creates a geocode dataflow job and uploads spatial data to process.
        //Parameters: 
        //   dataFilePath: The path to the file that contains the spatial data to geocode.
        //   dataFormat: The format of the input data. Possible values are xml, csv, tab and pipe.
        //   key: The Bing Maps Key to use for this job. The same key is used to get job status and download results.
        //   description: Text that is used to describe the geocode dataflow job. 
        //Return value : A URL that defines the location of the geocode dataflow job that was created.
        static string CreateJob(string dataFilePath, string dataFormat, string key, string description)
        {
            //Define parameters for the HTTP request
            //
            // The 'Content-Type' header of the HTTP Request must be "text/plain" or "application/xml"
            // depending on the input data format.
            //
            string contentType = "text/plain";
            if (dataFormat.Equals("xml", StringComparison.OrdinalIgnoreCase))
                contentType = "application/xml";

            StringBuilder queryStringBuilder = new StringBuilder();

            //
            // The 'input'(input format) and 'key' (Bing Maps Key) parameters are required.
            //
            queryStringBuilder.Append("input=").Append(Uri.EscapeUriString(dataFormat));
            queryStringBuilder.Append("&");
            queryStringBuilder.Append("key=").Append(Uri.EscapeUriString(key));

            if (!String.IsNullOrEmpty(description))
            {
                //
                // The 'description' parameter is optional.
                //
                queryStringBuilder.Append("&");
                queryStringBuilder.Append("description=").Append(Uri.EscapeUriString(description));
            }

            //Build the HTTP URI that will upload and create the geocode dataflow job
            UriBuilder uriBuilder = new UriBuilder("http://spatial.virtualearth.net");
            uriBuilder.Path = "/REST/v1/dataflows/geocode";
            uriBuilder.Query = queryStringBuilder.ToString();

            //Include the data to geocode in the HTTP request
            using (FileStream dataStream = File.OpenRead(dataFilePath))
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriBuilder.Uri);

                //
                // The HTTP method must be 'POST'.
                //
                request.Method = "POST";
                request.ContentType = contentType;

                using (Stream requestStream = request.GetRequestStream())
                {
                    byte[] buffer = new byte[16384];
                    int bytesRead = dataStream.Read(buffer, 0, buffer.Length);
                    while (bytesRead > 0)
                    {
                        requestStream.Write(buffer, 0, bytesRead);

                        bytesRead = dataStream.Read(buffer, 0, buffer.Length);
                    }
                }

                //Submit the HTTP request and check if the job was created successfully. 
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    //
                    // If the job was created successfully, the status code should be
                    // 201 (Created) and the 'Location' header should contain a URL
                    // that defines the location of the new dataflow job. You use this 
                    // URL with the Bing Maps Key to query the status of your job.
                    //
                    if (response.StatusCode != HttpStatusCode.Created)
                        throw new Exception("An HTTP error status code was encountered when creating the geocode job.");

                    string dataflowJobLocation = response.GetResponseHeader("Location");
                    if (String.IsNullOrEmpty(dataflowJobLocation))
                        throw new Exception("The 'Location' header is missing from the HTTP response when creating a goecode job.");

                    return dataflowJobLocation;
                }
            }
        }
    }


}
